module rt70_subpixel_ctrl(
dclk,
reset_n,

in_de,
in_r,
in_g,
in_b,
in_end_frame,
in_goa_endframe,

pix_sft_en,
sft_dir,
sft_sel,

chrb,
di,

nml_de, 
nml_rgb,
data_sft_rgb

);


input dclk;
input reset_n;

input       in_de;
input [7:0] in_r;               //r,g,b 8bit
input [7:0] in_g;
input [7:0] in_b;
input       in_end_frame;
input       in_goa_endframe;

input       pix_sft_en;
input       sft_dir;
input [2:0] sft_sel;         

input chrb;
input di;

output        nml_de;
output [23:0] nml_rgb;
output        data_sft_rgb;

reg in_end_frame_d1;
always @(posedge dclk or negedge reset_n)
begin
 if (!reset_n)
 in_end_frame_d1 <= 1'd0;
 else
 in_end_frame_d1 <= in_end_frame; 
end


//sft_sel func
reg [7:0] in_r_d1, in_g_d1, in_b_d1,
          in_r_d2, in_g_d2, in_b_d2,
          in_r_d3, in_g_d3, in_b_d3, in_b_d4;
reg in_de_d1, in_de_d2, in_de_d3, in_de_d4;                
always @(posedge dclk or negedge reset_n)
begin
 if (!reset_n)
 begin
    in_de_d1 <= 1'd0;
    in_r_d1  <= 8'd0; 
    in_g_d1  <= 8'd0; 
    in_b_d1  <= 8'd0;
    
    in_de_d2 <= 1'd0;
    in_r_d2  <= 8'd0;
    in_g_d2  <= 8'd0;
	  in_b_d2  <= 8'd0;
    
    in_de_d3 <= 1'd0;
    in_r_d3 <= 8'd0;
    in_g_d3 <= 8'd0;
    in_b_d3 <= 8'd0;
    
    in_de_d4 <= 1'd0;
    in_b_d4  <= 8'd0;
 end else begin
    in_de_d1 <= in_de;
    in_r_d1  <= in_r;
    in_g_d1  <= in_g;
    in_b_d1  <= in_b;
    
   	in_de_d2 <= in_de_d1;
    in_r_d2  <= in_r_d1;
    in_g_d2  <= in_g_d1;
    in_b_d2  <= in_b_d1;

    in_de_d3 <= in_de_d2;
    in_r_d3  <= in_r_d2;
    in_g_d3  <= in_g_d2;
    in_b_d3  <= in_b_d2;
    
   	in_de_d4 <= in_de_d3;
    in_b_d4  <= in_b_d3;
    end
end

wire de_pe = in_de & (~in_de_d1);
wire de_d1_pe = in_de_d1 & (~in_de_d2);
wire end_frame_pe = in_end_frame & (~in_end_frame_d1);

reg [1:0] de_pe_no;
always @(posedge dclk or negedge reset_n)
begin 
if (!reset_n)
 de_pe_no <= 2'd3;
else begin 
     if (end_frame_pe)
        de_pe_no <= 2'd3;
     else if (de_pe) 
          de_pe_no <= de_pe_no + 2'd1;
          else 
          de_pe_no <= de_pe_no;
          end
end


reg data_sft_rgb;
always @(posedge dclk or negedge reset_n)
begin 
if (!reset_n)
 data_sft_rgb <= 1'd0;
else if (pix_sft_en == 1'd0)
 data_sft_rgb <= 1'd0; 
else if (de_d1_pe) begin
     case ({sft_sel, de_pe_no})
     //sft_sel=000
     5'b00000: data_sft_rgb <= 1'd0;
     5'b00001: data_sft_rgb <= 1'd1;
     5'b00010: data_sft_rgb <= 1'd0;
     5'b00011: data_sft_rgb <= 1'd1;
     //sft_sel=001
     5'b00100: data_sft_rgb <= 1'd0;
     5'b00101: data_sft_rgb <= 1'd0;
     5'b00110: data_sft_rgb <= 1'd1;
     5'b00111: data_sft_rgb <= 1'd1;
     //sft_sel=010
     5'b01000: data_sft_rgb <= 1'd0;
     5'b01001: data_sft_rgb <= 1'd1;
     5'b01010: data_sft_rgb <= 1'd1;
     5'b01011: data_sft_rgb <= 1'd0;
     //sft_sel=100
     5'b10000: data_sft_rgb <= 1'd1;
     5'b10001: data_sft_rgb <= 1'd0;
     5'b10010: data_sft_rgb <= 1'd1;
     5'b10011: data_sft_rgb <= 1'd0;
     //sft_sel=101
     5'b10100: data_sft_rgb <= 1'd1;
     5'b10101: data_sft_rgb <= 1'd1;
     5'b10110: data_sft_rgb <= 1'd0;
     5'b10111: data_sft_rgb <= 1'd0;
     //sft_sel=110 
     5'b11000: data_sft_rgb <= 1'd1;
     5'b11001: data_sft_rgb <= 1'd0;
     5'b11010: data_sft_rgb <= 1'd0;
     5'b11011: data_sft_rgb <= 1'd1;
     default:  data_sft_rgb <= 1'd0;
     endcase
     end
     else
     data_sft_rgb <= data_sft_rgb;
end



//pix
reg [7:0] sft_r;
reg [7:0] sft_g;
reg [7:0] sft_b;
reg sft_de;
always @(posedge dclk or negedge reset_n)
begin 
if (!reset_n)
  begin
     sft_de <= 1'd0;
     sft_r  <= 8'd0;
	   sft_g  <= 8'd0;
	   sft_b  <= 8'd0;
 end else begin
     casex ({pix_sft_en, sft_dir, data_sft_rgb})
     3'b0xx:begin
            sft_de <= in_de_d3;
            sft_r <= in_r_d3;
            sft_g <= in_g_d3;
            sft_b <= in_b_d3;
            end

     3'b100:begin
            sft_de <= in_de_d3 | in_de_d4;
            sft_r <= in_r_d3;
            sft_g <= in_g_d3;
            sft_b <= in_b_d3;
            end
			  
     3'b101:begin
            sft_de <= in_de_d3 | in_de_d4;
            sft_r <= in_b_d4;
            sft_g <= in_r_d3;
            sft_b <= in_g_d3;
            end
			  
     3'b110:begin 
            sft_de <= in_de_d2 | in_de_d3;
            sft_r <= in_r_d3;
            sft_g <= in_g_d3;
            sft_b <= in_b_d3;
            end
			  
     3'b111:begin 
            sft_de <= in_de_d2 | in_de_d3;
            sft_r <= in_b_d2;
            sft_g <= in_r_d3;
            sft_b <= in_g_d3;
            end
            
     default:begin
             sft_de <= in_de_d3;
             sft_r <= in_r_d3;
             sft_g <= in_g_d3;
             sft_b <= in_b_d3;
             end     
     endcase
     end
end



//data_swap
reg [7:0] swap_r, swap_g, swap_b;
reg swap_de;
always@(posedge dclk or negedge reset_n)
begin
if (!reset_n)
  begin
     swap_de <= 1'd0;
     swap_r  <= 8'd0;
	   swap_g  <= 8'd0;
	   swap_b  <= 8'd0;
 end else if ( chrb )begin
     swap_de <= sft_de;
     swap_r  <= sft_b;
     swap_g  <= sft_g;
     swap_b  <= sft_r;
	   end else begin
         swap_de <= sft_de;
         swap_r  <= sft_r;
         swap_g  <= sft_g;
         swap_b  <= sft_b;
		 end
end



////data_inv////
wire [7:0] nml_r = di ? (~swap_r) : swap_r;
wire [7:0] nml_g = di ? (~swap_g) : swap_g;
wire [7:0] nml_b = di ? (~swap_b) : swap_b;


////mix rgb data////

reg [23:0] nml_rgb;
reg nml_de;
always@(posedge dclk or negedge reset_n)
begin
if (!reset_n)
 begin
  nml_rgb <= 24'd0;
  nml_de <= 1'd0;
 end else begin
   nml_de <= swap_de;
   nml_rgb <= {nml_r, nml_g, nml_b}; end
end



endmodule